home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
3D GFX
/
3D GFX.iso
/
amiutils
/
i_l
/
irit5
/
cagd_lib
/
cagdcsrf.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-12-30
|
4KB
|
98 lines
/******************************************************************************
* CagdCSrf.c - Construct a surface using a set of curves. *
*******************************************************************************
* Written by Gershon Elber, Sep. 91. *
******************************************************************************/
#include "cagd_loc.h"
/*****************************************************************************
* DESCRIPTION: M
* Constructs a surface using a set of curves. Curves are made to be M
* compatible and then each is substituted into the new surface's mesh as a M
* row. M
* If the OtherOrder is less than the number of curves, number of curves is M
* used. M
* A knot vector is formed with uniform open end for the other direction, M
* so it interpolates the first and last curves. M
* Note, however, that only the first and the last curves are interpolated M
* if OtherOrder is greater than 2. M
* *
* PARAMETERS: M
* CrvList: List of curves to consturct a surface with. M
* OtherOrder: Other order of surface. M
* *
* RETURN VALUE: M
* CagdSrfStruct *: Constructed surface from curves. M
* *
* KEYWORDS: M
* CagdSrfFromCrvs, surface constructors M
*****************************************************************************/
CagdSrfStruct *CagdSrfFromCrvs(CagdCrvStruct *CrvList, int OtherOrder)
{
CagdBType IsNotRational;
int i, j, NumCrvs, UOrder, VOrder, MaxCoord, Length;
CagdRType **SrfPoints;
CagdCrvStruct *Crv, **CrvVec;
CagdSrfStruct *Srf;
/* Find out how many curves we have and put them in a linear vector. */
/* Note the vector have a COPY of the curves so we can modify them. */
for (NumCrvs = 0, Crv = CrvList;
Crv != NULL;
NumCrvs++, Crv = Crv -> Pnext);
CrvVec = (CagdCrvStruct **) IritMalloc(sizeof(CagdCrvStruct *) * NumCrvs);
for (i = 0, Crv = CrvList;
i < NumCrvs;
i++, Crv = Crv -> Pnext)
CrvVec[i] = CagdCrvCopy(Crv);
/* Traverse vector in a O(n^2) fashion and make all curves compatible. */
for (i = 0; i < NumCrvs - 1; i++)
for (j = i + 1; j < NumCrvs; j++)
CagdMakeCrvsCompatible(&CrvVec[i], &CrvVec[j], TRUE, TRUE);
/* Construct the surface. All required information is now available. */
UOrder = CrvVec[0] -> Order;
VOrder = MIN(NumCrvs, OtherOrder);
if (NumCrvs == VOrder && CrvVec[0] -> GType == CAGD_CBEZIER_TYPE) {
/* Allocate a bezier surface. */
Srf = BzrSrfNew(CrvVec[0] -> Length, NumCrvs, CrvVec[0] -> PType);
}
else {
/* Allocate a bspline surface. */
Srf = BspPeriodicSrfNew(CrvVec[0] -> Length, NumCrvs, UOrder, VOrder,
CrvVec[0] -> Periodic, FALSE,
CrvVec[0] -> PType);
IritFree((VoidPtr) Srf -> UKnotVector);
Srf -> UKnotVector = BspKnotCopy(CrvVec[0] -> KnotVector,
CAGD_CRV_PT_LST_LEN(CrvVec[0]) +
UOrder);
BspKnotUniformOpen(NumCrvs, VOrder, Srf -> VKnotVector);
}
/* Substitute each curve as a row into the surface mesh and delete it. */
SrfPoints = Srf -> Points;
i = 0;
MaxCoord = CAGD_NUM_OF_PT_COORD(CrvVec[0] -> PType),
IsNotRational = !CAGD_IS_RATIONAL_CRV(CrvVec[0]);
Length = CrvVec[0] -> Length;
for (j = 0; j < NumCrvs; j++) {
int k;
CagdRType
**CrvPoints = CrvVec[j] -> Points;
for (k = IsNotRational; k <= MaxCoord; k++)
CAGD_GEN_COPY(&SrfPoints[k][i], CrvPoints[k],
sizeof(CagdRType) * Length);
CagdCrvFree(CrvVec[j]);
i += Length;
}
IritFree((VoidPtr) CrvVec);
return Srf;
}